package gamebackend;

import framework.Color;
import generators.BasicBlockGenerator;
import generators.BlockRule;
import generators.EmbiggenGenerator;
import generators.PatternGenerator;
import generators.PipeGenerator;
import generators.ReplaceGenerator;
import generators.ScaredGenerator;
import gui.BlockStyle;

import java.util.Random;

public class SnakeBiome extends GameSession.Biome {
	/*
	 * This depends on the size of blocks and currently assumes they won't change.
	 */
	private static final double BEGINNING_LENGTH = 1000;
	private static final double HEAD_LENGTH = 330;
	private static final double TAIL_LENGTH = 600;
	private final Block my_white;
	private final Block my_gray;
	private static final String FOREGROUND =
			"    0     0    " +
			"   0       0   " +
			"  0         0  " +
			"  0         0  " +
			"  0         0  " +
			"   0       0   " +
			"   0       0   " +
			"   00     00   " +
			"    0     0    " +
			"     0   0     " +
			"               " +
			"               ";
//	private static final String BACKGROUND = 
//			"    0000000    " +
//			"   000000000   " +
//			"  00 00000 00  " +
//			"  0000   0000  " +
//			"  000     000  " +
//			"   000   000   " +
//			"   000000000   " +
//			"    000 000    " +
//			"    0000000    " +
//			"     00000     " +
//			"     0   0     ";
	private static final String BACKGROUND = 
			"    0000000    " +
			"   000000000   " +
			"  00 00000 00  " +
			"  0000   0000  " +
			"  000     000  " +
			"   000   000   " +
			"  00000000000  " +
			" 000000 000000 " +
			" 00 0000000 00 " +
			" 0   00000   0 " +
			" 00  0   0  00 " +
			"  0         0  ";

	private boolean my_headStarted;
	private boolean my_bodyStarted;
	private boolean my_tailStarted;
	private double my_distanceToBodySwap = HEAD_LENGTH + BEGINNING_LENGTH;
	private final FlightPath my_bodyPath;
	private final FlierWrapper my_bodyWrapper;
	final MultiFlier my_multi;
	private boolean my_wild = true;
	private final double my_wildChance;
	private final EasyFlier my_easyBodyFlier;
	private final DirectFlier my_directFlier;
	public SnakeBiome(GameSession the_session,
			int the_tier, Random the_random, double the_length) {
		the_session.super(the_session, the_tier, the_random, the_length);
		my_white = new Block(BlockStyle.ASTEROID, new Color(160, 160, 130));
		my_gray = new Block(BlockStyle.ASTEROID, new Color(40, 40, 40));
		addEasyPath(new FlightPath(Block.PRIMARY_PATH, getEasyPath(), 40), HEAD_LENGTH + BEGINNING_LENGTH);
		addHardPath(new FlightPath(Block.PRIMARY_PATH, getHardPath(), 40), HEAD_LENGTH + BEGINNING_LENGTH);
		my_multi = new MultiFlier();
		getEasyPath().getShipFlier().setTarget(getWidth() / 2);
		getHardPath().getShipFlier().setTarget(getWidth() / 2);
		setFlier(my_multi);
		final Ship bodyShip = new LaserShip(getGameSession().getWidth() / 2, 0);
		for (int i = 0; i < 4; i++) {
			bodyShip.boost();
		}
		my_bodyPath = new FlightPath(Block.PRIMARY_PATH, getExtraHeight(), 40,
				bodyShip);
		my_easyBodyFlier = new EasyFlier(my_bodyPath.getShipFlier(), getRandom(), -40, getGameSession().getWidth() + 40);
		my_directFlier = new DirectFlier(my_bodyPath.getShipFlier());
		
		my_wildChance = Math.min(.8, getTier() * .25 + .3);
		my_bodyWrapper = new FlierWrapper();
		
		
	}
	public void step(double the_yChange) {
		super.step(the_yChange);
		if (!my_headStarted && getCovered() > BEGINNING_LENGTH) {
			my_headStarted = true;
			addToMidGround(new PatternGenerator(my_gray, BACKGROUND), HEAD_LENGTH);
			addGenerator(new PatternGenerator(my_white, FOREGROUND), HEAD_LENGTH);
		}
		
		
		if (!my_bodyStarted && getCovered() > HEAD_LENGTH + BEGINNING_LENGTH) {
			my_bodyStarted = true;
			final double length = getLength() - getCovered();
			
			my_distanceToBodySwap = 0;
			
			addFlightPath(my_bodyPath, getLength() - getCovered());
			my_bodyWrapper.setFlier(my_easyBodyFlier);
			addEasyPath(new FlightPath(Block.SECONDARY_PATH, getEasyPath(), 30), length);
			addHardPath(new FlightPath(Block.SECONDARY_PATH, getHardPath(), 16), length);
			my_multi.add(my_bodyWrapper);
			my_multi.add(new EasyFlier(getEasyPath().getShipFlier(), getRandom(), 15, getGameSession().getWidth() - 15));
			my_multi.add(new EasyFlier(getHardPath().getShipFlier(), getRandom(), 8, getGameSession().getWidth() - 8));
			addGenerator(new PipeGenerator(Block.PRIMARY_PATH, my_white), length - TAIL_LENGTH);
			addToMidGround(new ReplaceGenerator(Block.PRIMARY_PATH, my_gray), length);
			addToMidGround(new BasicBlockGenerator(Block.EMPTY_BLOCK, BlockRule.ANY, getRandom(), .2), length - TAIL_LENGTH);
			if (getTier() == 0) {
				addGenerator(new ScaredGenerator(my_white, getRandom(), 0, .1 / 16, ScaredGenerator.SHY), length - TAIL_LENGTH);
			} else {
				addGenerator(new EmbiggenGenerator(my_white, BlockRule.EMPTY), length - TAIL_LENGTH);
			}
		}
		if (!my_tailStarted && getCovered() > getLength() - TAIL_LENGTH) {
			my_tailStarted = true;
			addToMidGround(new EmbiggenGenerator(Block.EMPTY_BLOCK, BlockRule.ANY), TAIL_LENGTH);
		}
		
		// determine whether to change the flier for the body
		my_distanceToBodySwap -= the_yChange;
		if (my_distanceToBodySwap <= 0) {
			my_distanceToBodySwap += 200;
			if (!my_wild && getRandom().nextDouble() < my_wildChance) {
				
				my_bodyWrapper.setFlier(my_easyBodyFlier);
				my_wild = true;
				//my_white.setColor(Color.RED);
			} else if (my_wild && getRandom().nextDouble() > my_wildChance){
				my_bodyWrapper.setFlier(my_directFlier);
				my_wild = false;
				//my_white.setColor(Color.WHITE);
			}
		}
		if (!my_wild) {
			my_directFlier.setTarget(getEasyPath().getXPosition());
		}
	}
	

}
